package game.module.payment.logic;

import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.swiftpass.action.SwiftpassOpenApi;

import game.entity.PlayingRole;
import game.module.item.dao.ShopTemplateCache;
import game.module.item.logic.ItemManager;
import game.module.payment.bean.PaymentBean;
import game.module.payment.dao.PaymentLogDao;
import game.module.template.ShopTemplate;
import game.util.CommUtil;
import lion.common.IdWorker;
import lua.LuaMessageHall.S2CPayPreOrder;

public class PaymentManager {

	private static Logger logger = LoggerFactory.getLogger(PaymentManager.class);

	private IdWorker uuIdGenerator;

	static class SingletonHolder {
		static PaymentManager instance = new PaymentManager();
	}

	private PaymentManager() {
		uuIdGenerator = new IdWorker(1);
	}

	public static PaymentManager getInstance() {
		return SingletonHolder.instance;
	}

	private Set<String> existOrderIdAll = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());

	/**
	 * 后台回调通知处理加金币等处理
	 */
	public synchronized String swiftpassCallNotify(String orderId, int total_fee) {
		if (PaymentManager.getInstance().checkOrderExist(orderId)) {
			logger.error("repeat pay callback orderId={},total_fee={}", orderId, total_fee);
			return "success";
		}
		PaymentManager.getInstance().addOrderId(orderId);
		PaymentBean bean = PaymentLogDao.getInstance().getPaymentByOrderId(orderId);
		if (bean == null) {
			logger.error("not found orderId={}", orderId);
			return "fail";
		}
		if (bean.getPay_status() != 0) {
			logger.error("Have already dealt with pay callback orderId={}", orderId);
			return "success";
		}
		if (bean.getPay_money() != total_fee) {
			logger.error("pay money not match total_fee={},payMoney={}", total_fee, bean.getPay_money());
			return "fail";
		}

		bean.setPay_status(1);
		PaymentLogDao.getInstance().finishPaymentStatus(orderId, 1);
		ItemManager.getInstance().gainItemsAndPush(bean.getPlayer_id(), bean.getItemId(), bean.getAdd_point() + bean.getReward_diamond());

		// TODO 处理 首冲 充值奖励 等条件

		return "success";
	}

	/**
	 * 预处理订单 swiftpass的 金额是 分需要 *100
	 * 
	 * @param hero
	 * @param shopId
	 */
	public void preOrderPay(PlayingRole hero, int shopId) {
		String orderId = generateOrderId();
		String clientIp = CommUtil.praseClientIp(hero.getGamePlayer().getAddress());
		int playerId = hero.getId();
		ShopTemplate st = ShopTemplateCache.getInstance().getShopTemplateByShopId(shopId);
		if (st == null || st.getCost() <= 0) {
			logger.error("eror shopId={}", shopId);
			S2CPayPreOrder respMsg = new S2CPayPreOrder();
			respMsg.status = "-2"; // 充值的金额有误
			respMsg.token_id = "";
			hero.writeAndFlush(respMsg.build(hero.alloc()));
			return;
		}
		int totalFee = st.getCost() * 100;
		String openId = hero.getPlayerBean().getAccountId();

		Map<String, String> retMap = SwiftpassOpenApi.getInstance().prePay(orderId, clientIp, st.getInfo(), totalFee, playerId);
		S2CPayPreOrder respMsg = new S2CPayPreOrder("", "");
		if (retMap == null || !retMap.containsKey("status")) {
			respMsg.status = "-1";
		} else if (!"0".equals(retMap.get("status"))) {
			respMsg.status = retMap.get("status");
		} else {
			respMsg.status = retMap.get("status");
			respMsg.token_id = retMap.get("token_id");
			// 成功后生成支付订单
			savePayOrder(st, openId, totalFee, playerId, orderId);
		}
		hero.writeAndFlush(respMsg.build(hero.alloc()));
	}

	private void savePayOrder(ShopTemplate st, String openId, int totalFee, int playerId, String orderId) {
		// 生成订单
		PaymentBean bean = new PaymentBean();
		bean.setAdd_point(st.getNum());
		bean.setAdd_time(new Date());
		Float rateNum = st.getNum() * st.getSalerate();
		bean.setReward_diamond(rateNum.intValue());
		bean.setOpen_id(openId);
		bean.setPay_money(totalFee);
		bean.setPay_status(0);
		bean.setPlayer_id(playerId);
		bean.setProduct_id(st.getId());
		bean.setTransaction_code(orderId);
		bean.setPay_way("Swiftpass");
		bean.setItemId(st.getItemid());
		PaymentLogDao.getInstance().saveTopupLogBean(bean);
	}

	/**
	 * 生成order id
	 * 
	 * @return
	 */
	public String generateOrderId() {
		return String.valueOf(uuIdGenerator.nextId());
	}

	public void addOrderId(String orderId) {
		existOrderIdAll.add(orderId);
	}

	public void removeOrderId(String orderId) {
		existOrderIdAll.remove(orderId);
	}

	public boolean checkOrderExist(String orderId) {
		return existOrderIdAll.contains(orderId);
	}

}
